#include "enviroment.h"

namespace mslite{

cl_platform_id Enviroment::platform_ = nullptr;
cl_device_id Enviroment::device_ = nullptr;
cl_context Enviroment::context_ = nullptr;
cl_command_queue Enviroment::queue_ = nullptr;

int Enviroment::createEnv(int targetPlatform) {
    void (*callback)(const char*, size_t, size_t, void*) = [](const char *buffer, size_t length, size_t final, void *user_data) -> void {
        fwrite(buffer, 1, length, stdout);
    };

    cl_int status;
    status = clGetPlatformIDs(targetPlatform, &Enviroment::platform_, NULL);   // 使用第一个平台
    cl_context_properties cprops[] = {CL_CONTEXT_PLATFORM, (cl_context_properties) Enviroment::platform_,     // 生成 context
                                      CL_PRINTF_CALLBACK_ARM, (cl_context_properties) callback,
                                      CL_PRINTF_BUFFERSIZE_ARM, (cl_context_properties) 0x100000, 0};
    Enviroment::context_ = clCreateContextFromType(cprops, CL_DEVICE_TYPE_GPU, NULL, NULL, &status);

    size_t deviceListSize;
    status = clGetContextInfo(Enviroment::context_, CL_CONTEXT_DEVICES, 0, NULL, &deviceListSize);
    std::vector<cl_device_id> devices(deviceListSize / sizeof(cl_device_id));
    status = clGetContextInfo(Enviroment::context_, CL_CONTEXT_DEVICES, deviceListSize, devices.data(), NULL);
    Enviroment::queue_ = clCreateCommandQueue(Enviroment::context_, devices[0], CL_QUEUE_PROFILING_ENABLE, &status);
    Enviroment::device_ = devices[0];
    return status;
}

int Enviroment::releaseEnv(void) {
    cl_int status;
    status = clReleaseCommandQueue(Enviroment::queue_);
    status = clReleaseContext(Enviroment::context_);
    return status;
}

}